using System.Diagnostics;
using System.Text;
using System.Text.Json;
using ChatGPT.Net;
using ChatGpt_WebApp;
using ChatGpt_WebApp.Fillter;
using ChatGpt_WebApp.ThirdApi;
using Forge.OpenAI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.FileProviders;
//using NLog.Extensions.Logging;
using NLog.Web;


var builder = WebApplication.CreateBuilder(args);

//读取配置文件
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
.Build();

AppSetting.Init(config);
TokenManager.LoadToken();

var gptConfig = AppSetting.Current!.ChatGpt;

// 配置swagger
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = "ChatGpt_WebApp", Version = "v1" });
});

//配置mvc
builder.Services.AddControllers(option =>
{
    option.Filters.Add<ActionFilter>();
    option.Filters.Add<GlobalExceptionFilter>();
}).AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    //日期格式化 yyyy-MM-dd HH:mm:ss
    options.JsonSerializerOptions.Converters.Add(new DateTimeConverter("yyyy-MM-dd HH:mm:ss"));
});


//配置跨域
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "MyCorsPolicy",
                      builder =>
                      {
                          builder.AllowAnyOrigin();
                      });
});

//配置nlog
builder.Services.AddLogging(loggingBuilder =>
{
    loggingBuilder.ClearProviders();
    loggingBuilder.SetMinimumLevel(LogLevel.Trace);
    loggingBuilder.AddNLog("nlog.config");
    builder.Host.UseNLog();
});

//配置chatgpt
builder.Services.AddChatGptApi(option =>
{
    var setting = AppSetting.Current!.ChatGpt;
    if (!setting.TokenPool.Any())
    {
        throw new Exception("没有配置任何SessionToken");
    }

    var token = setting.TokenPool[0];

    option.IsPlus = token.IsProUser;
    option.SessionToken = token.SessionToken;
    option.ConfigDir = Path.Combine(builder.Environment.ContentRootPath, "ChatGptConfig", token.Account ?? "tookenId_" + token.Id.ToString());
    option.ApiKey = token.ApiKey;
});

builder.Services.AddForgeOpenAI(options => {
        options.AuthenticationInfo = AppSetting.Current!.ChatGpt.TokenPool[0].ApiKey;
        options.BaseAddress = "https://f547046a.cloudflare-proxy.pages.dev/";
});

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireIpAddress", policy =>
    {
        policy.Requirements.Add(new IpAddressRequirement(AppSetting.Current!.AdminIps));  // 允许访问的 IP 地址列表
    });
});

//配置AllowSynchronousIO
builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});
builder.Services.Configure<IISServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});

builder.Services.AddSingleton(f => AppSetting.Current!);
builder.Services.AddSingleton(typeof(IChatApi),gptConfig.UseOfficialApi?typeof(OfficialChatGptApi):typeof(PawanReverseApi));
builder.Services.AddSingleton<IAuthorizationHandler, IpAddressAuthorizationHandler>();  // 注册授权处理程序
builder.Services.AddHttpContextAccessor();


var app = builder.Build();

//默认打开 wwwroot下的 index.html
//app.UseHttpsRedirection();

app.UseDefaultFiles();

app.UseStaticFiles();

// //生产环境下使用bin 目录下的 wwwroot
// if (!builder.Environment.IsDevelopment())
// {
//     app.UseStaticFiles(new StaticFileOptions
//     {
//         FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "wwwroot")),
//         RequestPath = "/wwwroot"
//     });
// }

//使用swagger
if (builder.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint(" ", "ChatGpt_WebApp v1"));
}

app.Use(async (context, next) =>
{
    try
    {
        var ip = context.Connection.RemoteIpAddress!.ToString();
        if (ip == "::1")
        {
            context.Connection.RemoteIpAddress = System.Net.IPAddress.Parse("127.0.0.1");
        }
        context.Connection.RemoteIpAddress = System.Net.IPAddress.Parse(ip.Replace(":ffff:", "").Replace("f", "").Replace(":", ""));
        context.Items["clientIp"] = context.Connection.RemoteIpAddress;
    }
    catch (System.Exception){}

    await next();
});

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseCors("MyCorsPolicy");

app.MapControllers();

await app.StartAsync();

//控制台打印启动的地址
foreach (var url in app.Urls)
{
    Console.WriteLine(url);
}

await app.WaitForShutdownAsync();
